<?php
	$host = "localhost";
	$dbusername = "progin";
	$dbpassword = "progin";
	$dbname = "progin_171_13509018";
	$cnx;

/*============================================================================/	
/==============================     KONEKSI     ==============================/
/*===========================================================================*/
	
	// return: true jika koneksi berhasil
	// membunuh program jika gagal
	function connect() {
		global $host, $dbusername, $dbpassword, $dbname, $cnx;
		
		$cnx = mysqli_connect($host, $dbusername, $dbpassword, $dbname) or die('haha');
		return true;
	}

	
/*============================================================================/	
/==============================      USER       ==============================/
/*===========================================================================*/	

	// return: jika login GAGAL: variabel dengan ['ID_user'] == -1, misalnya $user['achievement'] == -1
	// return: jika login BERHASIL: variabel dengan ['ID_user'], ['username'], ['achievement'] = ['nama_achievement'], ['icon_achievement']
	function getUserInfo($ID_user) {
		global $cnx;
		
		$query = "SELECT ID_user, username, nama_lengkap, password, avatar_path,email,gender,about FROM User WHERE ID_user='$ID_user'";
		$result = mysqli_query($cnx, $query);
		$ret;
		
		if ($result->num_rows == 0) {
			$ret['ID_user'] = -1;
			return $ret;
		}
		
		$result = mysqli_fetch_assoc($result);
		
		$ret['ID_user'] = $result['ID_user'];
		$ret['username'] = $result['username'];
		$ret['nama_lengkap'] = $result['nama_lengkap'];
		$ret['avatar_path'] = $result['avatar_path'];
		$ret['email'] = $result['email'];
		$ret['gender'] = $result['gender'];
		$ret['about'] = $result['about'];
		
		$query = "SELECT nama_achievement, icon FROM Achievement NATURAL JOIN (SELECT ID_achievement FROM User_Achievement WHERE ID_user='$ID_user') T1";
		$ach = mysqli_query($cnx, $query);
		
		$ret['achievement'] = array();
		while ($row = mysqli_fetch_assoc($ach)) {
			$val['nama_achievement'] = $row['nama_achievement'];
			$val['icon'] = $row['icon'];
			array_push($ret['achievement'], $val);
		}
		
		$ret['contents'] = getContentsList("SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM Konten NATURAL JOIN User WHERE ID_user=$ID_user", 9999);
		
		return $ret;
	}
	
	
	// BERES
	// Cari user dengan username, email, nama, ATAU about
	// return: ID_user, username, nama lengkap, avatar_path, about
	function searchUser($keyword, $number=10, $page=0, $sort='username', $desc=false) {
		global $cnx;
		
		$keyword = mysqli_real_escape_string($cnx, $keyword);
		
		$lim0 = $page*10;
		$lim1 = $page*10 + $number;
		
		$query = "SELECT ID_user, username, nama_lengkap, avatar_path, about FROM User WHERE username LIKE '%$keyword%' OR email LIKE '%$keyword%' OR nama_lengkap LIKE '%$keyword%' OR about LIKE '%$keyword%' " . (($sort == "") ? "" : "ORDER BY $sort " . (($desc) ? "DESC " : "")) . "LIMIT $lim0, $lim1";
				
		$retval = array();
		$result = mysqli_query($cnx, $query);
		if ($result->num_rows == 0)
			return $retval;
		
		while ($row = mysqli_fetch_assoc($result)) {
			$val['ID_user'] = $row['ID_user'];
			$val['username'] = $row['username'];
			$val['nama_lengkap'] = $row['nama_lengkap'];
			$val['avatar_path'] = $row['avatar_path'];
			$val['about'] = $row['about'];
			
			$retval[$row['ID_user']] = $val;
		}
		
		return $retval;
	}

	// BERES
	// return: jika login GAGAL: variabel dengan ['ID_user'] == -1, misalnya $user['achievement'] == -1
	// return: jika login BERHASIL: variabel dengan ['ID_user'], ['username'], ['achievement'] = ['nama_achievement'], ['icon_achievement']
	function login($username, $password) {
		global $cnx;
		
		$query = "SELECT ID_user, username, nama_lengkap, password, avatar_path,email,gender,about FROM User WHERE username='$username'";
		$result = mysqli_query($cnx, $query);
		$ret;
		
		if ($result->num_rows == 0) {
			$ret['ID_user'] = -1;
			return $ret;
		}
		
		$result = mysqli_fetch_assoc($result);
		if (md5($password) != $result['password']) {
			$ret['ID_user'] = -1;
			return $ret;
		}
		
		$ret['ID_user'] = $result['ID_user'];
		$ret['username'] = $result['username'];
		$ret['nama_lengkap'] = $result['nama_lengkap'];
		$ret['avatar_path'] = $result['avatar_path'];
		$ret['email'] = $result['email'];
		$ret['gender'] = $result['gender'];
		$ret['about'] = $result['about'];
		updateWaktuLoginTerakhir($ret['ID_user']);
		
		$query = "SELECT nama_achievement, icon FROM Achievement NATURAL JOIN (SELECT ID_achievement FROM User_Achievement WHERE ID_user=${ret['ID_user']}) T1";
		$ach = mysqli_query($cnx, $query);
		
		$ret['achievement'] = array();
		while ($row = mysqli_fetch_assoc($ach)) {
			$val['nama_achievement'] = $row['nama_achievement'];
			$val['icon'] = $row['icon'];
			array_push($ret['achievement'], $val);
		}
		
		return $ret;
	}
	
	// BERES
	// return: true kalo $username ga ada di User.username
	function isUsernameUnique($username) {
		global $cnx;
		
		$query = "SELECT username FROM User WHERE username IN ('$username')";
		return !(mysqli_fetch_row(mysqli_query($cnx, $query)));
	}
	
	// BERES
	// return: true jika $email belum ada di User.email
	function isEmailUnique($email) {
		global $cnx;
		
		$query = "SELECT email FROM User WHERE email IN ('$email')";
		return !(mysqli_fetch_row(mysqli_query($cnx, $query)));
	}
	
	// BERES
	// asumsi: user sudah dipreprocess dan valid
	// return true jika INSERT berhasil
	function addUser($user) {
		global $cnx;
		
		$emptyAvatar = (strlen($user['avatar_path']) == 0);
		
		$query = "INSERT INTO User(username, password, email, nama_lengkap, tanggal_lahir, gender, " . ($emptyAvatar ? "" : "avatar_path, ") . "tanggal_daftar, waktu_login_terakhir, about) VALUES ('${user['username']}', MD5('${user['password']}'), '${user['email']}', '${user['nama_lengkap']}', '${user['tanggal_lahir']}', '${user['gender']}', " . ($emptyAvatar ? "" : "'${user['avatar_path']}', ") . "NOW(), NOW(), '${user['about']}')";
		
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_affected_rows($cnx)) != 1)		// Ada kesalahan
			return false;
			
		return true;
	}
	
	// BERES
	// return: objek user
	function createUserObject($username, $password, $conf_password, $email, $nama_lengkap, $tanggal_lahir, $gender, $avatar_path, $about) {
		$user = array();
		$user['username'] = $username;
		$user['password'] = $password;
		$user['conf_password'] = $conf_password;
		$user['email'] = $email;
		$user['nama_lengkap'] = $nama_lengkap;
		$user['tanggal_lahir'] = $tanggal_lahir;
		$user['gender'] = $gender;
		$user['avatar_path'] = $avatar_path;
		$user['about'] = $about;
		
		return $user;
	}
	
	// BERES
	// user = username, password, conf_password, email, nama_lengkap, tanggal_lahir, gender, avatar_path, about
	// user SUDAH di preprocess
	// return: array of pesan kesalahan, ukuran = 0 jika user valid 
	function isUserValid($user) {
		$pesan = array();
		
		if (strlen($user['username']) == 0) {
			array_push($pesan, "Username tidak boleh kosong");
		} else if (!isUsernameUnique($user['username'])) {
			array_push($pesan, "Username sudah ada di database");
		}
		
		if (strlen($user['email']) == 0) {
			array_push($pesan, "Email tidak boleh kosong");
		} else if (!isEmailUnique($user['email'])) {
			array_push($pesan, "Email sudah ada di database");
		}
		
		if (strlen($user['password']) < 4) {
			array_push($pesan, "Panjang password minimal 4 karakter");
		}
		
		if ($user['password'] !== $user['conf_password']) {
			array_push($pesan, "Password tidak sama dengan konfirmasi password");
		}
		
		if (strlen($user['nama_lengkap']) == 0) {
			array_push($pesan, "Nama lengkap tidak boleh kosong");
		}
		
		if (!isDate($user['tanggal_lahir'])) {
			array_push($pesan, "Tanggal lahir salah (Format: YYYY-MM-DD)");
		}
		
		if (($user['gender'] != 'L') && ($user['gender'] != 'P')) {
			array_push($pesan, "Pilih jenis kelamin");
		}
		if ((strlen($user['avatar_path']) > 0) && (!isJPG($user['avatar_path']))) {
			array_push($pesan, "Avatar path harus kosong atau file .jpg / .jpeg");
		}
		
		return $pesan;
	}
	
	// BERES
	// return: pesan kesalahan jika gagal
	// return: string kosong jika berhasil
	function updateEmail($ID_user, $email) {
		global $cnx;
		
		$query = "SELECT email FROM User WHERE email='$email' AND ID_user!=$ID_user";
		if (mysqli_fetch_row(mysqli_query($cnx, $query))) {
			return "Email sudah digunakan. Silakan berikan email lain";
		}
		
		$query2 = "UPDATE User SET email='$email' WHERE ID_user=$ID_user";
		mysqli_query($cnx, $query2);
		if (mysqli_affected_rows($cnx) < 0)
			return "Terjadi kesalahan";
		return "";
	}
	
	// BERES
	// return: true jika tidak ada error
	function updateAbout($ID_user, $about) {
		global $cnx;
		
		$query = "UPDATE User SET about='$about' WHERE ID_user='$ID_user'";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)
			return false;
		return true;
	}
	
	function updateWaktuLoginTerakhir($ID_user) {
		global $cnx;
		
		$query = "UPDATE User SET waktu_login_terakhir=NOW() WHERE ID_user='$ID_user'";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)
			return false;
		return true;
	}
	
	function updateAvatar($ID_user, $avatar_path) {
		global $cnx;
		
		$query = "UPDATE User SET avatar_path='$avatar_path' WHERE ID_user='$ID_user'";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)
			return false;
		return true;
	}
	
	// BERES
	function printUsersList($users) {
		if (empty($users)) {
			echo "List user kosong";
			return;
		}
		
		foreach ($users as $user) {
			printUser($user);
			echo "<br />";
		}
	}
	
	// BERES
	function printUser($user) {
		if (empty($user)) {
			echo "User tidak ditemukan";
			return;
		}
		foreach ($user as $field => $value) {
			echo "<b>$field:</b> $value<br />";
		}
	}
	
	// BERES
	// memproses data user sebelum insert atau update ke database
	function preprocessUser($user) {
		global $cnx;
		
		$user['username'] = mysqli_real_escape_string($cnx, trim($user['username']));
		$user['email'] = mysqli_real_escape_string($cnx, trim($user['email']));
		$user['nama_lengkap'] = mysqli_real_escape_string($cnx, trim($user['nama_lengkap']));
		$user['about'] = mysqli_real_escape_string($cnx, trim($user['about']));
		
		if (strlen($user['avatar_path']) > 0) {
			$ext = strtolower(substr(strrchr($user['avatar_path'], '.'), 1));
			$user['avatar_path'] = "images/avatar/${user['username']}.$ext";
		}
		
		return $user;
	}
	
	// BERES
	// return: jumlah konten yang telah dipost oleh user, -1 jika gagal
	function getNumContent($ID_user, $tipe='') {
		global $cnx;
		
		$query = "SELECT COUNT(ID_konten) FROM Konten WHERE ID_user=$ID_user" . (($tipe) ? " AND tipe='$tipe'" : "");
		if (!$result = mysqli_query($cnx, $query))
			return -1;
		
		$row = mysqli_fetch_row($result);
		return $row[0];
	}
	
	
/*============================================================================/	
/==============================     KONTEN      ==============================/
/*===========================================================================*/	

	// BERES
	// Cari konten dengan judul, tag, ATAU komentar
	// return: ID_konten, ID_user, username, judul, waktu, URL, count view
	function searchContent($keyword, $number=10, $page=0, $sort="time", $desc=true) {
		global $cnx;
		
		
		$keyword = mysqli_real_escape_string($cnx, $keyword);
		$query = "SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM (SELECT * FROM ((SELECT ID_konten FROM Konten WHERE judul LIKE '%$keyword%') UNION (SELECT ID_konten FROM Konten_Tag NATURAL JOIN Tag WHERE nama_tag='$keyword') UNION (SELECT ID_konten  FROM Komentar WHERE isi LIKE '%$keyword%')) T2 NATURAL JOIN Konten) T3 NATURAL JOIN User";
		
		return getContentsList($query, $number, $page, $sort, $desc);
	}
	
	// BERES
	// return: list of contents (ID_konten, judul, waktu, URL, deskripsi (mungkin null), ID_user, username, total like, total comment, )
	function getContentsByTag($filter, $number=10, $page=0, $sort="time", $desc=true) {
		$filter = trim($filter);
		if ($filter == "") {
			$query = "SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM Konten NATURAL JOIN User";
		} else {
			$query = "SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM Konten NATURAL JOIN User WHERE ID_konten IN (SELECT ID_konten FROM Konten_Tag NATURAL JOIN Tag WHERE " . generateTagClause($filter) . ")";
		}
		
		return getContentsList($query, $number, $page, $sort, $desc);
	}
	
	// BERES
	// return: $inter['satuan'] = ('tahun', 'bulan', 'hari', 'jam', 'menit', atau 'detik') dan $inter['selisih']
	function getContentTimeInterval($waktu) {
		$skrg = date("Y-m-d H:i:s");
		
		if (($inter['selisih'] = (substr($skrg, 0, 4) - substr($waktu, 0, 4))) > 0) {
			$inter['satuan'] = "tahun";
		} else if (($inter['selisih'] = (substr($skrg, 5, 2) - substr($waktu, 5, 2))) > 0) {
			$inter['satuan'] = "bulan";
		} else if (($inter['selisih'] = (substr($skrg, 8, 2) - substr($waktu, 8, 2))) > 0) {
			$inter['satuan'] = "hari";
		} else if (($inter['selisih'] = (substr($skrg, 11, 2) - substr($waktu, 11, 2))) > 0) {
			$inter['satuan'] = "jam";
		} else if (($inter['selisih'] = (substr($skrg, 14, 2) - substr($waktu, 14, 2))) > 0) {
			$inter['satuan'] = "menit";
		} else if (($inter['selisih'] = (substr($skrg, 17, 2) - substr($waktu, 17, 2))) > 0) {
			$inter['satuan'] = "detik";
		}
		return $inter;
	}
	
	// BERES
	// Memeriksa apakah input post sudah valid
	// prekondisi: data SUDAH dipreprocessContent
	// return: array of pesan kesalahan
	// REGEX URL dan URL youtube belum
	function isContentValid($content) {
		$pesan = array();
		
		if (strlen($content['judul']) == 0) {
			$pesan['judul'] = "Judul tidak boleh kosong";
		}
		
		if (($content['tipe'] != 'Gambar') && ($content['tipe'] != 'Link') && ($content['tipe'] != 'Video')) {
			$pesan['tipe'] = "Pilih tipe konten";
		}
		
		if (strlen($content['URL']) == 0) {
			if ($content['tipe'] == 'Gambar')
				$pesan['URL'] = "Path tidak boleh kosong";
			else
				$pesan['URL'] = "URL tidak boleh kosong";
		} else {
			if (($content['tipe'] == 'Gambar') && !isJPG($content['URL'])) {
				$pesan['URL'] = "File gambar harus bertipe .jpg atau .jpeg";
			} else if (($content['tipe'] == 'Link') && !isURLValid($content['URL'])) {
				$pesan['URL'] = "URL tidak valid";
			} else if (($content['tipe'] == 'Video') && !isURLValid($content['URL'], true)) {
				$pesan['URL'] = "URL YouTube tidak valid";
			}
		}
		
		if (($content['tipe'] == 'Link') && (strlen($content['deskripsi']) == 0)) {
			$pesan['deskripsi'] = "Deskripsi tidak boleh kosong";
		}
		
		if (sizeof($content['tags']) == 0) {
			$pesan['tags'] = "Tag tidak boleh kosong";
		}
		
		return $pesan;
	}
	
	// BERES
	// asumsi: ID_user valid, content SUDAH divalidasi
	// return: true jika INSERT berhasil
	function addContent($ID_user, $content) {
		global $cnx;
		
		// Tambahkan konten
		$query = "INSERT INTO Konten(ID_user, judul, waktu, tipe, URL, deskripsi) VALUES ($ID_user, '${content['judul']}', NOW(), '${content['tipe']}', '${content['URL']}', '${content['deskripsi']}')";
		
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) <= 0) {
			return false;
		}
		
		// Cari ID_konten yang baru ditambahkan
		$query = "SELECT MAX(ID_konten) FROM Konten";
		$ID_konten = mysqli_fetch_row(mysqli_query($cnx, $query));
		$ID_konten = $ID_konten[0];
		
		// Cari nama_tag apa saja yang baru
		$init_tags = array();
		foreach ($content['tags'] as $value) {
			array_push($init_tags, "$value");
		}
		
		$query = "SELECT nama_tag FROM Tag WHERE nama_tag IN (";
		foreach ($content['tags'] as $value) {
			$query .= "'$value', ";
		}
		$query = substr($query, 0, strlen($query)-2) . ")";
		
		$result = mysqli_query($cnx, $query);
		while ($row = mysqli_fetch_row($result)) {
			if (($index = array_search($row[0], $init_tags)) !== false)
				unset($init_tags[$index]);
		}
		
		// Kalau ada tag baru, tambahkan ke database
		if (sizeof($init_tags) > 0) {
			$query = "INSERT INTO Tag(nama_tag) VALUES ";
			foreach ($init_tags as $value) {
				$query .= "('$value'), ";
			}
			$query = substr($query, 0, strlen($query)-2);
			
			mysqli_query($cnx, $query);
			if (mysqli_affected_rows($cnx) != sizeof($init_tags)) {
				return false;
			}
		}
		
		// Cari ID_tag dari tag2 konten
		$query = "SELECT ID_tag FROM Tag WHERE nama_tag IN (";
		foreach ($content['tags'] as $value) {
			$query .= "'$value', ";
		}
		$query = substr($query, 0, strlen($query)-2) . ")";
		$result = mysqli_query($cnx, $query);
		$insert_tag_IDs = array();
		while ($row = mysqli_fetch_row($result)) {
			array_push($insert_tag_IDs, $row[0]);
		}
		
		// Masukkan ID_tag tersebut ke database
		$query = "INSERT INTO Konten_TAG(ID_konten, ID_tag) VALUES ";
		foreach ($insert_tag_IDs as $value) {
			$query .= "($ID_konten, '$value'), ";
		}
		$query = substr($query, 0, strlen($query)-2);
		
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != sizeof($insert_tag_IDs)) {
			return false;
		}
		
		return true;
	}
	
	// BERES
	// return: array tag (ID_tag, nama_tag)
	function getAllTags() {
		global $cnx;
		
		$query = "SELECT * FROM Tag ORDER BY nama_tag";
		$retval = array();
		if (!$result = mysqli_query($cnx, $query))
			return $retval;
			
		while ($row = mysqli_fetch_assoc($result)) {
			$val['ID_tag'] = $row['ID_tag']; 
			$val['nama_tag'] = $row['nama_tag'];
			array_push($retval, $val);
		}
		return $retval;
	}
	
	// BERES
	// return: $konten, isinya: ID_konten, ID_user, username, avatar_path, judul, waktu, tipe, URL, deskripsi, list of tags (ID_tag, nama_tag), list of comments (ID_komentar, ID_user, username, avatar_path, waktu, isi), views, comments, likes
	// jika ID tidak ditemukan, return array kosong
	function getContentDetail($ID) {
		global $cnx;
		$content = array();
		
		$query = "SELECT ID_user, username, avatar_path, judul, waktu, tipe, URL, deskripsi FROM Konten NATURAL JOIN User WHERE ID_konten=$ID";
		$result = mysqli_query($cnx, $query);
		if ($result->num_rows == 0)
			return $content;
		
		$row = mysqli_fetch_assoc($result);
		$content['ID_konten'] = $ID;
		$content['ID_user'] = $row['ID_user'];
		$content['username'] = $row['username'];
		$content['avatar_path'] = $row['avatar_path'];
		$content['judul'] = $row['judul'];
		$content['waktu'] = getContentTimeInterval($row['waktu']);
		$content['tipe'] = $row['tipe'];
		$content['URL'] = $row['URL'];
		$content['deskripsi'] = $row['deskripsi'];
		$content['tags'] = array();
		$content['user_comments'] = array();
		$content['views'] = 0;
		$content['comments'] = 0;
		$content['likes'] = 0;
		
		$query = "SELECT ID_tag, nama_tag FROM Tag NATURAL JOIN Konten_Tag WHERE ID_konten=$ID";
		if ($result = mysqli_query($cnx, $query)) {
			while ($row = mysqli_fetch_assoc($result)) {
				array_push($content['tags'], $row);
			}
		}
		
		$query = "SELECT ID_komentar, ID_user, username, avatar_path, waktu, isi FROM Komentar NATURAL JOIN User WHERE ID_konten=$ID order by waktu desc";
		if ($result = mysqli_query($cnx, $query)) {
			while ($row = mysqli_fetch_assoc($result)) {
				array_push($content['user_comments'], $row);
			}
			$content['comments'] = sizeof($content['user_comments']);
		}
		
		
		$query = "SELECT COUNT(ID_user) FROM User_View WHERE ID_konten=$ID GROUP BY ID_konten";
		if ($result = mysqli_query($cnx, $query)) {
			$row = mysqli_fetch_row($result);
			$content['views'] = $row[0];
		}
		
		$query = "SELECT like_value, COUNT(ID_user) total_like FROM User_Like WHERE ID_konten=$ID GROUP BY ID_konten, like_value";
		if ($result = mysqli_query($cnx, $query)) {
			$row = mysqli_fetch_assoc($result);
			if ($row['like_value'] == 1)
				$content['likes'] += $row['total_like'];
			else
				$content['likes'] -= $row['total_like'];
				
			if ($row = mysqli_fetch_assoc($result)) {
				if ($row['like_value'] == 1)
					$content['likes'] += $row['total_like'];
				else
					$content['likes'] -= $row['total_like'];
			}
		}
		
		return $content;
	}
	
	// BERES
	// return: list of contents dengan query $query
	function getContentsList($query, $number=10, $page=0, $sort="time", $desc=true) {
		global $cnx;
		
		$lim0 = $page*$number;
		$lim1 = $page*$number + $number;
		$retval = array();
		if ($sort != "") {
			switch ($sort) {
				case "like":
					$query = "SELECT T5.ID_konten, T5.ID_user, username, judul, T5.waktu, tipe, URL, deskripsi, COUNT(Komentar.ID_komentar) total_comment, total_view, total_like FROM (SELECT T4.ID_konten, T4.ID_user, username, judul, T4.waktu, tipe, URL, deskripsi, total_like, COUNT(User_View.ID_user) total_view FROM (SELECT T3.ID_konten, T3.ID_user, username, judul, T3.waktu, tipe, URL, deskripsi, SUM(User_Like.like_value) total_like FROM (SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM (" . $query .") T2 NATURAL JOIN User) T3 LEFT OUTER JOIN User_Like ON T3.ID_konten=User_Like.ID_konten GROUP BY ID_konten ORDER BY total_like DESC LIMIT $lim0, $lim1) T4 LEFT OUTER JOIN User_View ON T4.ID_konten=User_View.ID_konten GROUP BY ID_konten) T5 LEFT OUTER JOIN Komentar ON T5.ID_konten=Komentar.ID_konten GROUP BY ID_konten ORDER BY total_like DESC";
					break;
				case "comment":
					$query = "SELECT T5.ID_konten, T5.ID_user, username, judul, waktu, tipe, URL, deskripsi, total_view, total_comment, SUM(like_value) total_like FROM (SELECT T4.ID_konten, T4.ID_user, username, judul, T4.waktu, tipe, URL, deskripsi, total_comment, COUNT(User_View.ID_user) total_view FROM (SELECT T3.ID_konten, T3.ID_user, username, judul, T3.waktu, tipe, URL, deskripsi, COUNT(Komentar.ID_komentar) total_comment FROM (SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM (" . $query .") T2 NATURAL JOIN User) T3 LEFT OUTER JOIN Komentar ON T3.ID_konten=Komentar.ID_konten GROUP BY ID_konten ORDER BY total_comment DESC LIMIT $lim0, $lim1) T4 LEFT OUTER JOIN User_View ON T4.ID_konten=User_View.ID_konten GROUP BY ID_konten) T5 LEFT OUTER JOIN User_Like ON T5.ID_konten=User_Like.ID_konten GROUP BY ID_konten ORDER BY total_comment DESC";
					break;
				case "view":
					$query = "SELECT T5.ID_konten, T5.ID_user, username, judul, waktu, tipe, URL, deskripsi, total_view, total_comment, SUM(like_value) total_like FROM (SELECT T4.ID_konten, T4.ID_user, username, judul, T4.waktu, tipe, URL, deskripsi, total_view, COUNT(Komentar.ID_komentar) total_comment FROM (SELECT T3.ID_konten, T3.ID_user, username, judul, T3.waktu, tipe, URL, deskripsi, COUNT(User_view.ID_user) total_view FROM (SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM (" . $query .") T2 NATURAL JOIN User) T3 LEFT OUTER JOIN User_View ON T3.ID_konten=User_View.ID_konten GROUP BY ID_konten ORDER BY total_view DESC LIMIT $lim0, $lim1) T4 LEFT OUTER JOIN Komentar ON T4.ID_konten=Komentar.ID_konten GROUP BY ID_konten) T5 LEFT OUTER JOIN User_Like ON T5.ID_konten=User_Like.ID_konten GROUP BY ID_konten ORDER BY total_view DESC";
					break;
				case "time":
					$query = "SELECT T5.ID_konten, T5.ID_user, username, judul, waktu, tipe, URL, deskripsi, total_view, total_comment, SUM(like_value) total_like FROM (SELECT T4.ID_konten, T4.ID_user, username, judul, T4.waktu, tipe, URL, deskripsi, total_view, COUNT(Komentar.ID_komentar) total_comment FROM (SELECT T3.ID_konten, T3.ID_user, username, judul, T3.waktu, tipe, URL, deskripsi, COUNT(User_view.ID_user) total_view FROM (SELECT ID_konten, ID_user, username, judul, waktu, tipe, URL, deskripsi FROM (" . $query .") T2 NATURAL JOIN User ORDER BY waktu DESC LIMIT $lim0, $lim1) T3 LEFT OUTER JOIN User_View ON T3.ID_konten=User_View.ID_konten GROUP BY ID_konten) T4 LEFT OUTER JOIN Komentar ON T4.ID_konten=Komentar.ID_konten GROUP BY ID_konten) T5 LEFT OUTER JOIN User_Like ON T5.ID_konten=User_Like.ID_konten GROUP BY ID_konten ORDER BY waktu DESC";
					break;
			}
		}
		
		$result = mysqli_query($cnx, $query);
		if (mysqli_num_rows($result) == 0) {
			return $retval;
		}
		
		while ($row = mysqli_fetch_assoc($result)) {
			$val['ID_konten'] = $row['ID_konten'];
			$val['ID_user'] = $row['ID_user'];
			$val['username'] = $row['username'];
			$val['judul'] = $row['judul'];
			$val['waktu'] = getContentTimeInterval($row['waktu']);
			$val['tipe'] = $row['tipe'];
			$val['URL'] = $row['URL'];
			$val['deskripsi'] = ($row['deskripsi'] == null) ? "" : $row['deskripsi'];
			$val['views'] = $row['total_view'];
			$val['comments'] = $row['total_comment'];
			$val['likes'] = ($row['total_like'] == null) ? 0 : $row['total_like'];
			
			$retval[$row['ID_konten']] = $val;
		}
		
		return $retval;
	}
	
	// BERES
	// return: like = 1, neutral = 0, dislike = -1, gagal = false
	function like($ID_user, $ID_konten, $like=1) {
		global $cnx;
		
		$query = "SELECT like_value FROM User_Like WHERE ID_user=$ID_user AND ID_konten=$ID_konten";
		if (!$result = mysqli_query($cnx, $query))
			return false;
		
		if (mysqli_num_rows($result) == 0) {
			$query = "INSERT INTO User_Like(ID_user, ID_konten, like_value) VALUES ($ID_user, $ID_konten, $like)";
		} else {
			$row = mysqli_fetch_row($result);
			$like_value = $row[0];
			if ($like == $like_value) {
				$query = "DELETE FROM User_Like WHERE ID_user=$ID_user AND ID_konten=$ID_konten";
				$like = 0;
			} else {
				$query = "UPDATE User_Like SET like_value=$like WHERE ID_user=$ID_user AND ID_konten=$ID_konten";
			}
		}
		
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != 1)
			return false;
		return $like;
	}
	
	// BERES
	function printContentsList($contents, $printComments=true, $printTags=true) {
		if (empty($contents)) {
			echo "List konten kosong";
			return;
		}
			
		foreach ($contents as $content) {
			printContent($content, $printComments, $printTags);
			echo "<br />";
		}
	}
	
	// BERES
	function printContent($content, $printComments=true, $printTags=true) {
		if (empty($content)) {
			echo "Konten tidak ditemukan";
			return;
		}
		
		foreach ($content as $field => $value) {
			if (($field == 'user_comments') && $printComments) {
				if (empty($value))
					echo "<b>Komentar:</b> Tidak ada komentar<br />";
				else {
					echo "<br /><b>Komentar:</b><br />";
					foreach ($value as $comment) {
						foreach ($comment as $commentField => $commentValue) {
							echo "<b>$commentField:</b> $commentValue<br />";
						}
						echo "<br />";
					}
				}
			} else if (($field == 'tags') && $printTags) {
				if (empty($value))
					echo "<b>Tag:</b> Tidak ada tag<br />";
				else {
					echo "<br /><b>Tag:</b><br />";
					foreach ($value as $tag) {
						foreach ($tag as $tagField => $tagValue) {
							echo "<b>$tagField:</b> $tagValue<br />";
						}
						echo "<br />";
					}
				}
			} else 
				echo "<b>$field:</b> $value<br />";
		}
	}
	
	// BERES
	// return: string untuk where clause dengan filter tag $filter
	function generateTagClause($filter) {
		$filter = str_replace(array("\\", "'"), "", $filter);
		$tags = explode(' ', $filter);
		
		$where = "";
		for ($i = 0; $i < count($tags); $i++) {
			$value = $tags[$i];
			if ($value == "")
				continue;
			if (($value == "(") || ($value == ")")) {
				$where .= $value;
				continue;
			}
			$upper = strtoupper($value);
			if (($upper == "OR") || ($upper == "AND") || ($upper == "NOT")) {
				$where .= "$upper ";
				continue;
			}
			
			if ($value[0] == "(") {
				if ($value[strlen($value) - 1] == ")") {	// "(tag)"
					$value = "(nama_tag LIKE '" . substr($value, 1, strlen($value) - 2) . "')";
				} else {		// "(tag"
					$value = "(nama_tag LIKE '" . substr($value, 1, strlen($value) - 1) . "'";
				}
			} else {
				if ($value[strlen($value) - 1] == ")") {	// "tag)"
					$value = "nama_tag LIKE '" . substr($value, 0, strlen($value) - 1) . "')";
				} else {		// "tag"
					$value = "nama_tag LIKE '$value'";
				}
			}
			
			$where .= "$value ";
		}
		
		return $where;
	}
	
	// BERES
	// memproses data konten sebelum insert atau update ke database
	function preprocessContent($content) {
		global $cnx;
		
		$content['judul'] = mysqli_real_escape_string($cnx, trim($content['judul']));
		$content['URL'] = mysqli_real_escape_string($cnx, trim($content['URL']));
		if ($content['tipe'] == 'Link') {
			$content['deskripsi'] = mysqli_real_escape_string($cnx, trim($content['deskripsi']));
		} else {
			$content['deskripsi'] = "";
		}
		$content['tags'] = explode(",", mysqli_real_escape_string($cnx, str_replace(" ", "", $content['tags'])));
		while ((($end = sizeof($content['tags']) - 1) >= 0)  && ($content['tags'][$end] == "")) {
			unset($content['tags'][$end]);
		}
		$content['tags'] = array_unique($content['tags']);
		
		return $content;
	}
	
	// BERES
	// asumsi: ID_konten ada di database
	// return: true jika konten berhasil dihapus (tidak ada kesalahan)
	function deleteContent($ID_konten) {
		global $cnx;
		
		// Hapus dari Komentar
		$query = "DELETE FROM Komentar WHERE ID_konten=$ID_konten";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0) {
			return false;
		}
		
		// Hapus dari Konten_Tag
		$query = "DELETE FROM Konten_Tag WHERE ID_konten=$ID_konten";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0) {
			return false;
		}
		
		// Hapus dari User_View
		$query = "DELETE FROM User_View WHERE ID_konten=$ID_konten";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0) {
			return false;
		}
		
		// Hapus dari User_Like
		$query = "DELETE FROM User_Like WHERE ID_konten=$ID_konten";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0) {
			echo "LAH KENAPE LIKENYE";
			return false;
		}
		
		// Hapus beneran dari Konten
		$query = "DELETE FROM Konten WHERE ID_konten=$ID_konten";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != 1) {
			return false;
		}
		
		return true;
	}
	
	// BERES
	// return: true jika user belum pernah liat konten, dan insert ke database berhasil
	function view($ID_user, $ID_konten) {
		global $cnx;
		
		$query = "SELECT * FROM User_View WHERE ID_user=$ID_user AND ID_konten=$ID_konten";
		if (mysqli_num_rows(mysqli_query($cnx, $query)) != 0) {		// Ada kesalahan atau sudah diview
			return false;
		}
		
		$query = "INSERT INTO User_View(ID_user, ID_konten) VALUES($ID_user, $ID_konten)";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != 1) {		// Ada kesalahan
			return false;
		}
		return true;
	}
	
	
/*============================================================================/	
/==============================    KOMENTAR     ==============================/
/*===========================================================================*/
	
	// BERES
	// return: true kalo database berubah
	function addComment($ID_user, $ID_konten, $isi) {
		global $cnx;
		
		$query = "INSERT INTO Komentar(ID_user, ID_konten, waktu, isi) VALUES($ID_user, $ID_konten, NOW(), '$isi')";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) <= 0)
			return false;
		return true;
	}
	
	// BERES
	// return: true kalo database berubah
	function deleteComment($ID_komentar) {
		global $cnx;
		
		$query = "DELETE FROM Komentar WHERE ID_komentar=$ID_komentar";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) <= 0)
			return false;
		return true;
	}
	
	
/*============================================================================/	
/==============================      PESAN      ==============================/
/*===========================================================================*/

	// BERES
	// asumsi: ID_user_dari dan semua ID_user_kepada valid, ID_user_dari tidak terdapat pada ID_user_kepada
	// return: true jika message berhasil dikirim (INSERT tidak ada kesalahan)
	// false jika kirim ke diri sendiri atau ada kesalahan
	function sendMessage($ID_user_dari, $ID_user_kepada, $subjek, $isi) {
		global $cnx;
		
		$subjek = mysqli_real_escape_string($cnx, trim($subjek));
		if (strlen($subjek) == 0) {		// Ganti dengan subjek default
			$subjek = "<NO SUBJECT>";
		}
		$isi = mysqli_real_escape_string($cnx, trim($isi));
		if (strlen($isi) == 0) {		// Ganti dengan isi default
			$isi = "<EMPTY MESSAGE>";
		}
		
		// INSERT pesan ke database
		$query = "INSERT INTO Pesan(ID_user_dari, waktu, subjek, isi) VALUES ($ID_user_dari, NOW(), '$subjek', '$isi')";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != 1)	// Ada kesalahan
			return false;
				
		// Cari ID_pesan yang baru di-INSERT
		$query = "SELECT MAX(ID_pesan) FROM Pesan";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) != 1))		// Ada kesalahan
			return false;
		
		$row = mysqli_fetch_row($result);
		$ID_pesan = $row[0];
		
		$query = "INSERT INTO Pesan_Kepada(ID_pesan, ID_user_kepada) VALUES ";
		foreach ($ID_user_kepada as $value) {
			$query .= "($ID_pesan, $value), ";
		}
		$query = substr($query, 0, strlen($query) - 2);
		
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) != sizeof($ID_user_kepada)) {		// Ada kesalahan
			return false;
		}
		return true;
	}
	
	// BERES
	// order: waktu, username, dibaca, subjek
	// header pesan: ID_user_dari, username, waktu, dibaca, subjek
	// return: list of header pesan yang belum dihapus
	function getInbox($ID_user, $number=10, $page=0, $sort='waktu', $desc=true) {
		global $cnx;
		$retval = array();
		$lim0 = $page*10;
		$lim1 = $lim0 + $number;
		
		// Ambil header pesan
		$query = "SELECT ID_pesan, ID_user_dari, username, waktu, dibaca, subjek FROM (SELECT ID_pesan, ID_user_dari, waktu, dibaca, subjek FROM Pesan NATURAL JOIN Pesan_Kepada WHERE ID_user_kepada=$ID_user AND dihapus=0) T1 INNER JOIN User ON T1.ID_user_dari=User.ID_user  ORDER BY $sort " . (($desc) ? "DESC " : "") . "LIMIT $lim0, $lim1";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) == 0))		// Ada kesalahan atau user tidak memiliki pesan
			return $retval;
		
		// Isi setiap header pesan ke returnvalue
		while ($row = mysqli_fetch_assoc($result)) {
			$retval[$row['ID_pesan']] = array();
			foreach ($row as $key => $value) {
				$retval[$row['ID_pesan']][$key] = $value;
			}
		}
		
		return $retval;
	}
	
	// BERES
	// asumsi: pesan benar untuk user dan belum dihapus
	// return: ID_pesan, ID_user_dari, username, penerima: list of (ID_user_kepada, username), waktu, subjek, isi
	function readMessage($ID_user, $ID_pesan) {
		global $cnx;
		$retval = array();
	
		// Ambil header pesan
		$query = "SELECT ID_pesan, ID_user_dari, username, waktu, subjek, isi FROM Pesan INNER JOIN User ON Pesan.ID_user_dari=User.ID_user WHERE ID_pesan=$ID_pesan";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) != 1))		// Ada kesalahan
			return array();
		
		// Masukkan header ke retval
		$row = mysqli_fetch_assoc($result);
		foreach ($row as $key => $value) {
			$retval[$key] = $value;
		}
		
		// Ambil list of penerima
		$query = "SELECT ID_user_kepada, username FROM Pesan_Kepada INNER JOIN User ON Pesan_Kepada.ID_user_kepada=User.ID_user WHERE ID_pesan=$ID_pesan";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) == 0)) {
			return array();
		}
		
		// Masukkan list of penerima ke retval
		$retval['penerima'] = array();
		while ($row = mysqli_fetch_assoc($result)) {
			array_push($retval['penerima'], array('ID_user_kepada' => $row['ID_user_kepada'], 'username' => $row['username']));
		}
		
		// UPDATE dibaca menjadi true untuk user dan pesan ini
		$query = "UPDATE Pesan_Kepada SET dibaca=1 WHERE ID_pesan=$ID_pesan AND ID_user_kepada=$ID_user";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) == -1)		// Ada kesalahan
			return array();
		
		return $retval;
	}
	
	// BERES
	// asumsi: semua ID_pesan (jika ada) ada di database dan benar tertuju untuk ID_user
	// jika $list_ID_pesan = array kosong, maka markAllAsRead
	// return: true jika tidak ada kesalahan
	function markAsRead($ID_user, $list_ID_pesan=array()) {
		global $cnx;
		
		$query = "UPDATE Pesan_Kepada SET dibaca=1 WHERE ID_user_kepada=$ID_user" . ((sizeof($list_ID_pesan) == 0) ? "" : " AND ID_pesan IN (" . implode($list_ID_pesan, ", ") . ")");
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)		// Ada kesalahan
			return false;
		return true;
	}
	
	// asumsi: semua ID_pesan (jika ada) ada di database dan benar tertuju untuk user
	// jika list_ID_pesan = array kosong, hapus SEMUA pesan user
	// definisi hapus: tandai dihapus = 1
	// return: true jika semua hapus berhasil (tidak ada kesalahan)
	function deleteMessages($ID_user, $list_ID_pesan=array()) {
		global $cnx;
		
		$query = "UPDATE Pesan_Kepada SET dihapus=1 WHERE ID_user_kepada=$ID_user" . ((sizeof($list_ID_pesan) == 0) ? "" : " AND ID_pesan IN (" . implode($list_ID_pesan, ", ") . ")");
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)		// Ada kesalahan
			return false;
			
		return true;
	}
	
	// BERES
	function printInbox($headers) {
		if (empty($headers)) {
			echo "Inbox kosong";
		}
		
		foreach ($headers as $header) {
			foreach ($header as $key => $value) {
				echo "<b>$key:</b> $value<br />";
			}
			echo "<br />";
		}
	}
	
	// BERES
	function printMessage($message) {
		foreach ($message as $key => $value) {
			if ($key == 'penerima') {
				echo "<br /><b>Penerima:</b><br />";
				foreach ($value as $penerima) {
					foreach ($penerima as $field => $val) {
						echo "<b>$field:</b> $val<br />";
					}
					echo "<br />";
				}
				
			} else {
				echo "<b>$key:</b> $value<br />";
			}
		}
	}
	
	
/*============================================================================/	
/==============================   ACHIEVEMENT   ==============================/
/*===========================================================================*/	
	
	// BERES
	// return: ID_achievement, nama_achievement, icon, deskripsi, atau array kosong jika achievement tidak ada / terjadi kesalahan
	function getAchievement($ID_achievement) {
		global $cnx;
		
		$retval = array();
		$query = "SELECT * FROM Achievement WHERE ID_achievement=$ID_achievement";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) != 1))		// Ada kesalahan
			return $retval;
		
		$row = mysqli_fetch_assoc($result);
		foreach ($row as $key => $value) {
			$retval[$key] = $value;
		}
		
		return $retval;
	}
	
	// BERES
	// asumsi: ID_achievement ada di database
	// return: true jika user sudah memiliki achievement tsb, false jika ada kesalahan
	function userHasAchievement($ID_user, $ID_achievement) {
		global $cnx;
		
		$query = "SELECT * FROM User_Achievement WHERE ID_user=$ID_user AND ID_achievement=$ID_achievement";
		if ((!$result = mysqli_query($cnx, $query)) || (mysqli_num_rows($result) == 0))		// Ada kesalahan atau user belum memiliki achievement
			return false;
		
		return true;
	}
	
	// BERES
	// asumsi: user belum memiliki achievement -> cek dulu dengan 
	// return: true jika INSERT berhasil
	function addAchievement($ID_user, $ID_achievement) {
		if (userHasAchievement($ID_user, $ID_achievement))
			return false;
			
		global $cnx;
		
		$query = "INSERT INTO User_Achievement(ID_user, ID_achievement) VALUES($ID_user, $ID_achievement)";
		mysqli_query($cnx, $query);
		if (mysqli_affected_rows($cnx) < 0)
			return false;
		return true;
	}
	
	// BERES
	// asumsi: ID_user benar
	// mengembalikan achievement2 baru yg diperoleh user ketika mempost
	// return: list of achievement (ID_achievement, nama_achievement, icon, deskripsi)
	// return: array kosong jika tidak ada achievement baru, achievement sudah diperoleh, atau terjadi kesalahan
	function checkAchievementPost($ID_user) {
		$retval = array();
		if ($achievement = checkAchievementNumPost($ID_user))
			array_push($retval, $achievement);
		if ($achievement = checkAchievementNumPost($ID_user, 'Gambar'))
			array_push($retval, $achievement);
		
		return $retval;
	}
	
	// BERES
	// asumsi: ID_user benar
	// return: ID_achievement, nama_achievement, icon, deskripsi
	// return: array kosong jika tidak ada achievement, achievement sudah diperoleh, atau terjadi kesalahan
	function checkAchievementNumPost($ID_user, $tipe='') {
		global $cnx;
	
		$num = getNumContent($ID_user);
		$ID_achievement = 0;
		
		// Hard-coded checking
		switch ($num) {
			case 1:
				switch ($tipe) {
					case '':
						$ID_achievement	= 1;
						break;
					case 'Gambar':
						$ID_achievement	= 8;
						break;
				}
				break;
			case 5:
				switch ($tipe) {
					case '':
						$ID_achievement	= 2;
						break;
					case 'Gambar':
						$ID_achievement	= 9;
						break;
				}
			case 10:
				switch ($tipe) {
					case '':
						$ID_achievement	= 3;
						break;
					case 'Gambar':
						$ID_achievement	= 10;
						break;
				}
		}
		
		if (($ID_achievement == 0) || !addAchievement($ID_user, $ID_achievement))		// Tidak ada achievement baru
			return array();
		
		return getAchievement($ID_achievement);
	}


/*============================================================================/	
/==============================    LAIN-LAIN    ==============================/
/*===========================================================================*/

	// BERES
	// return: true jika nama file .jpg atau .jpeg
	function isJPG($URL) {
		$ext = strtolower(substr(strrchr($URL, '.'), 1));
		return ($ext == 'jpg' || $ext == 'jpeg');
	}
	
	// BERES
	// $youtube: true untuk validasi URL YouTube
	// return: true jika URL valid
	function isURLValid($URL, $youtube=false) {
		$exp_protocol = "(https?://)?";
		
		if (!$youtube) {
			$exp_domain = "(www\.)(\w+\.)+[A-Za-z][A-Za-z]+?";
			$exp_get = "([^&\s]+=[^&\s]*&)*([^&\s]+=[^&\s]*)";
			$exp_file = "((/(${exp_get})?)|(\?${exp_get})|((/\w+)*/\w+((\.\w{1,4}(\?${exp_get})?)|(((/(${exp_get})?)|(\?${exp_get}))?))))?";
			$expr = "[^${exp_protocol}${exp_domain}${exp_file}$]i";
		}
		else {
			$exp_domain = "(www\.)youtube.co(m|(\.[A-Za-z]{2}))/watch\?";
			$exp_get = "([^&\sv]+=[^&\s]*&)*v=[^&\s]+(&[^&\sv]+=[^&\s]*)*";
			$expr = "[^${exp_protocol}${exp_domain}${exp_get}$]i";
		}
		
		return preg_match($expr, $URL);
	}
	
	// BERES
	// return: true jika $date merupakan tanggal yang (format "YYYY-MM-DD" dan sesuai pertanggalan)
	function isDate($date) {
		if (strlen($date) != 10)
			return false;
		
		$bulan = substr($date, 5, 2);
		if (!is_numeric($bulan))
			return false;
		
		$hari = substr($date, 8, 2);
		if (!is_numeric($hari))
			return false;
		
		$tahun = substr($date, 0, 4);
		if (!is_numeric($tahun))
			return false;
			
		return checkdate($bulan, $hari, $tahun);
	}
	
?>